package com.ljc.jsouphttpclient;


import cn.hutool.core.date.DateUtil;
import com.ljc.jsouphttpclient.dto.BizCommonHouseInfo;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.apache.commons.lang3.StringUtils;

import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import static cn.hutool.core.thread.ThreadUtil.sleep;

/**
 * @Date: 2021/5/6 16:26
 * @Author: ljc
 * @Description: 抓取anjuke小区列表及详情信息
 * 安居客小区列表页：https://m.anjuke.com/su/xiaoqu/
 * 安居客小区详情页：https://m.anjuke.com/su/community/269414/
 *
 * todo: 目前页面上看到的有12页数据，其他未显示的，可以查询到35页，第36页无数据
 * 其中第35页url：https://m.anjuke.com/su/xiaoqu-p35/
 */
public class JsoupNotLogin {

    /**
     * 分页数据
     * <span class="seo_pages">
     *         <a class="active" href="https://m.anjuke.com/su/xiaoqu/">1</a>
     *             <a  href="https://m.anjuke.com/su/xiaoqu-p2/">2</a>
     *             <a  href="https://m.anjuke.com/su/xiaoqu-p3/">3</a>
     *             <a  href="https://m.anjuke.com/su/xiaoqu-p4/">4</a>
     *             <a  href="https://m.anjuke.com/su/xiaoqu-p5/">5</a>
     *             <a  href="https://m.anjuke.com/su/xiaoqu-p6/">6</a>
     *             <span class="dot">...</span>  <!-- 省略符 -->
     *     </span>
     *     <span class="nextPage"><a href="https://m.anjuke.com/su/xiaoqu-p2/">下一页</a></span>
     * <div style="display:none;">
     * <span class="seo_pages">
     *     <a  href="https://m.anjuke.com/su/xiaoqu-p7/">7</a>
     *     <a  href="https://m.anjuke.com/su/xiaoqu-p8/">8</a>
     *     <a  href="https://m.anjuke.com/su/xiaoqu-p9/">9</a>
     *     <a  href="https://m.anjuke.com/su/xiaoqu-p10/">10</a>
     *     <a  href="https://m.anjuke.com/su/xiaoqu-p11/">11</a>
     *     <a  href="https://m.anjuke.com/su/xiaoqu-p12/">12</a>
     * </div>
     */
    //首页
//    String url = "https://m.anjuke.com/su/xiaoqu/";
    //第七页
//    String url = "https://m.anjuke.com/su/xiaoqu-p7/";
    //第十二页
    static String url = "https://m.anjuke.com/su/xiaoqu-p12/";

    public static void main(String[] args) {
//        String url = "https://m.anjuke.com/su/xiaoqu/";
        JsoupNotLogin jsoupNotLogin = new JsoupNotLogin();
        try {
            jsoupNotLogin.crawlerAnjukeHouse(url);
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("爬取完成！");
    }

    /**
     * todo 真实测试后，发现每个区域的小区列表都是一样的，所以只需要拉取全部的小区列表即可
     * @param url
     * @throws IOException
     */
    public void crawlAnjukeHouseCommonInfo(String url) throws IOException {

        // jsoup解析网页，返回浏览器document对象，所有在js可以使用的方法这里都能用！
        Document document = Jsoup.parse(new URL(url), 30000);  //url 最长解析时间
        Elements elements = document.getElementsByClass("listcont cont_hei");

        //获取elements下所有子节点的a标签元素
        Elements elementsA = elements.select("a[href]");

        for (Element el : elementsA) {
            //获取html中a标签的href值
            String areaUrl = el.attr("href");
            //获取html中a标签的文本值
            String areaName = el.getElementsByTag("a").eq(0).text();

            //System.out.println(img);
            System.out.println("区域查询地址：" + areaUrl);
            System.out.println("区域名称：" + areaName);

            //todo 真实测试后，发现每个区域的小区列表都是一样的，所以只需要拉取全部的小区列表即可
//            if ("相城".equals(areaName)) {
//                //拉取小程序小区地址
//                crawlAnjukeVillageData(areaUrl, areaName);
//            }


        }
    }

    public void crawlAnjukeVillageData(String areaUrl, String areaName) throws IOException {

        // jsoup解析网页，返回浏览器document对象，所有在js可以使用的方法这里都能用！
        Document document = Jsoup.parse(new URL(areaUrl), 30000);  //url 最长解析时间
        //获取items下方所有的a标签
        Elements elements = document.getElementsByClass("items");

        //获取elements下所有子节点的a标签元素
        Elements elementsA = elements.select("a[href]");

        List<BizCommonHouseInfo> bizCommonHouseInfoList = new ArrayList<>();

        for (Element el : elementsA) {
            //获取html中a标签的href值
            String villageDetailUrl = el.attr("href");
            //获取html中a标签的文本值
            String villageName = el.getElementsByTag("a").eq(0).text();

            System.out.println("===================小区列表信息===================");
            System.out.println("小区查询地址：" + villageDetailUrl);
            System.out.println("小区名称：" + villageName);
            System.out.println("====================================");

            //睡眠保护，随机数2-8秒，防止被封IP
            sleep((int) (Math.random() * (8000 - 2000 + 1) + 2000));

            //获取小区详情页面信息
//                bizCommonHouseInfoList.add(crawlAnjukeVillageDetailData(villageDetailUrl, villageName));
            BizCommonHouseInfo info = crawlAnjukeVillageDetailData(villageDetailUrl, villageName);

            //todo 查询该小区数据在数据库里是否存在，若不存在，则写入数据库，否则不写入
            //todo 单个保存到数据库

        }

//            if (ListUtils.isNotEmpty(bizCommonHouseInfoList)) {
//                //批量保存到数据库
//                bizCommonHouseInfoMapper.batchInsertBizCommonHouseInfo(bizCommonHouseInfoList);
//            }

        //获取下一页的地址
        Elements elementsNext = document.getElementsByClass("nextPage");
        //获取nextPage span中html的 a标签的href值
        String nextPageUrl = elementsNext.select("a[href]").attr("href");
        if (StringUtils.isNotBlank(nextPageUrl)) {
            System.out.println("下一页地址：" + nextPageUrl);
            //有下一页地址，则递归获取下一页小区列表数据
            //截取以下字符串中的数字6， https://m.anjuke.com/su/xiaoqu-p6/
            String nextPageNum = nextPageUrl.substring(nextPageUrl.lastIndexOf("p") + 1, nextPageUrl.lastIndexOf("/"));
            //判断nextPageNum是否为偶数
            if (StringUtils.isNotEmpty(nextPageNum) && Integer.parseInt(nextPageNum) % 2 == 0) {
                //睡眠保护，随机数2-6秒，防止被封IP
                sleep((int) (Math.random() * (6000 - 2000 + 1) + 2000));
            }
            crawlAnjukeVillageData(nextPageUrl, areaName);
        }
    }

    public BizCommonHouseInfo crawlAnjukeVillageDetailData(String villageDetailUrl, String villageName) throws IOException {
        // jsoup解析网页，返回浏览器document对象，所有在js可以使用的方法这里都能用！
        Document document = Jsoup.parse(new URL(villageDetailUrl), 30000);  //url 最长解析时间
        //获取items下方所有的a标签
        Elements elements = document.getElementsByClass("address");
//        <p class="address" data-v-59981f84>
//            <span data-v-59981f84>吴江</span>
//            <span data-v-59981f84>同里</span>
//            <span data-npv="M_COMM_Page_Address" data-v-59981f84>同肖西路266号</span>
//            <img src="https://pages.anjukestatic.com/usersite/touch/img/m_detail/xq_propdetail_icon_local_v2@3x.png" data-npv="M_COMM_Page_AddressIcon" data-v-59981f84>
//        </p>
        //获取elements下所有span元素的文本内容
        Elements elementsSpan = elements.select("span");
        String areaName = elementsSpan.eq(0).text();
        String circleName = elementsSpan.eq(1).text();
        String address = elementsSpan.eq(2).text();

        BizCommonHouseInfo bizCommonHouseInfo = new BizCommonHouseInfo();
        bizCommonHouseInfo.setArea(areaName);
        bizCommonHouseInfo.setCircleName(circleName);
        bizCommonHouseInfo.setVillageName(villageName);
        bizCommonHouseInfo.setAddress(address);
        bizCommonHouseInfo.setCreatedTs(DateUtil.date());
        bizCommonHouseInfo.setCreatedTy(1L);


        System.out.println("===================小区详细信息===================");
        System.out.println("小区名称：" + villageName);
        System.out.println("区域名称：" + areaName);
        System.out.println("商圈名称：" + circleName);
        System.out.println("小区地址：" + address);
        System.out.println("====================================");

        return bizCommonHouseInfo;

    }

    public void crawlerAnjukeHouse(String url) throws IOException {
        //1. todo 删除数据库中全部旧数据，若存在的话

        //2. 抓取安居客苏州小区信息及对应的商圈和小区地址
        crawlAnjukeVillageData(url);
    }


    public void crawlAnjukeVillageData(String areaUrl) throws IOException {

        //循环分页获取小区列表数据
        for (int i = 13; i <= 36; i++) {
            System.out.println("i = " + i);
            areaUrl = "https://m.anjuke.com/su/xiaoqu-p" + i + "/";

            //判断nextPageNum是否为偶数
            if (i % 2 == 0) {
                //睡眠保护，随机数2-6秒，防止被封IP
                sleep((int) (Math.random() * (6000 - 2000 + 1) + 2000));
            }

            // jsoup解析网页，返回浏览器document对象，所有在js可以使用的方法这里都能用！
            Document document = Jsoup.parse(new URL(areaUrl), 30000);  //url 最长解析时间
            //获取items下方所有的a标签
            Elements elements = document.getElementsByClass("items");

            //获取elements下所有子节点的a标签元素
            Elements elementsA = elements.select("a[href]");

//            List<BizCommonHouseInfo> bizCommonHouseInfoList = new ArrayList<>();
            for (Element el : elementsA) {
                //获取html中a标签的href值
                String villageDetailUrl = el.attr("href");
                //获取html中a标签的文本值
                String villageName = el.getElementsByTag("a").eq(0).text();

                System.out.println("===================小区列表信息===================");
                System.out.println("小区查询地址：" + villageDetailUrl);
                System.out.println("小区名称：" + villageName);
                System.out.println("====================================");

                //每获取一个小区详情，则睡眠保护，随机数2-8秒，防止被封IP
                sleep((int) (Math.random() * (8000 - 2000 + 1) + 2000));

                //获取小区详情页面信息
                BizCommonHouseInfo info = crawlAnjukeVillageDetailData(villageDetailUrl, villageName);

                //todo 判断数据库中是否已有该小区数据，若有，则不插入
//                BizCommonHouseInfo infoQuery = new BizCommonHouseInfo();
//                infoQuery.setArea(info.getArea());
//                infoQuery.setVillageName(info.getVillageName());
//                infoQuery.setCircleName(info.getCircleName());
//                infoQuery.setAddress(info.getAddress());
//                List<BizCommonHouseInfo> infoDbs = bizCommonHouseInfoMapper.selectBizCommonHouseInfoList(infoQuery);
//                if (ListUtils.isEmpty(infoDbs)) {
//                    //单个保存到数据库，减缓访问速度，防止被封IP
//                    bizCommonHouseInfoMapper.insertBizCommonHouseInfo(info);
//                }

            }

        }


    }



}
